from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.utils import timezone
from django.db.models import Q
from rest_framework import generics, permissions, status, filters
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination
from .serializers import (
    UserSerializer, RegisterSerializer, ProfileSerializer,
    AdminUserSerializer, AdminUserCreateSerializer, AdminUserUpdateSerializer,
    UserListFilterSerializer, AdminUserBatchSerializer
)

class RegisterAPI(generics.GenericAPIView):
    """
    API endpoint for user registration.
    """
    serializer_class = RegisterSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": token.key
        })

class LoginAPI(ObtainAuthToken):
    """
    API endpoint for user login, returns auth token.
    """
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)

        # 更新用户最后登录时间
        user.last_login = timezone.now()
        user.save(update_fields=['last_login'])

        return Response({
            'token': token.key,
            'user_id': user.pk,
            'username': user.username,
            'email': user.email,
            'is_staff': user.is_staff
        })

class UserAPI(generics.RetrieveAPIView):
    """
    API endpoint to get user information.
    """
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

class UserProfileUpdateAPI(generics.UpdateAPIView):
    """
    API endpoint for admins to update a user's profile,
    including assigning an NFC card ID.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAdminUser]

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        profile_data = request.data.get('profile', {})
        
        # Update profile fields
        profile_serializer = ProfileSerializer(instance.profile, data=profile_data, partial=True)
        if profile_serializer.is_valid(raise_exception=True):
            profile_serializer.save()

        # Update user fields if any
        user_serializer = self.get_serializer(instance, data=request.data, partial=True)
        user_serializer.is_valid(raise_exception=True)
        user_serializer.save()

        return Response(user_serializer.data)

class UserSelfProfileUpdateAPI(generics.UpdateAPIView):
    """
    API endpoint for users to update their own profile,
    including avatar upload.
    """
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = ProfileSerializer

    def get_object(self):
        # Get or create profile for the current user
        try:
            return self.request.user.profile
        except:
            from .models import Profile
            return Profile.objects.create(user=self.request.user)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        # Return updated user data with profile
        user_serializer = UserSerializer(request.user)
        return Response(user_serializer.data)

class ChangePasswordAPI(APIView):
    """
    API endpoint for users to change their password.
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        current_password = request.data.get('current_password')
        new_password = request.data.get('new_password')

        if not current_password or not new_password:
            return Response({
                'error': '请提供当前密码和新密码'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Verify current password
        user = request.user
        if not user.check_password(current_password):
            return Response({
                'error': '当前密码不正确'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Validate new password length
        if len(new_password) < 6:
            return Response({
                'error': '新密码长度至少为6位'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Set new password
        user.set_password(new_password)
        user.save()

        return Response({
            'message': '密码修改成功'
        }, status=status.HTTP_200_OK)

class UpdateUsernameAPI(APIView):
    """
    API endpoint for users to update their username.
    """
    permission_classes = [permissions.IsAuthenticated]

    def patch(self, request):
        new_username = request.data.get('username')

        if not new_username:
            return Response({
                'error': '请提供新的用户名'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Validate username
        if len(new_username) < 3:
            return Response({
                'error': '用户名至少3个字符'
            }, status=status.HTTP_400_BAD_REQUEST)

        if len(new_username) > 20:
            return Response({
                'error': '用户名最多20个字符'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Check if username already exists
        if User.objects.filter(username=new_username).exclude(id=request.user.id).exists():
            return Response({
                'error': '用户名已存在'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Update username
        user = request.user
        user.username = new_username
        user.save()

        # Return updated user data
        user_serializer = UserSerializer(user)
        return Response(user_serializer.data, status=status.HTTP_200_OK)


# ==================== 管理员专用API视图 ====================

class AdminUserPagination(PageNumberPagination):
    """管理员用户列表分页器"""
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100

class AdminUserListAPI(generics.ListAPIView):
    """
    管理员获取用户列表API
    支持搜索、过滤、排序和分页
    """
    serializer_class = AdminUserSerializer
    permission_classes = [permissions.IsAdminUser]
    pagination_class = AdminUserPagination
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['username', 'email', 'first_name', 'last_name', 'profile__full_name']
    ordering_fields = ['id', 'username', 'email', 'date_joined', 'last_login', 'is_active', 'is_staff']
    ordering = ['-date_joined']  # 默认按注册时间倒序

    def get_queryset(self):
        """
        根据查询参数过滤用户列表
        """
        queryset = User.objects.select_related('profile').prefetch_related('access_logs')

        # 获取过滤参数
        is_staff = self.request.query_params.get('is_staff')
        is_active = self.request.query_params.get('is_active')
        has_face_data = self.request.query_params.get('has_face_data')
        has_nfc_card = self.request.query_params.get('has_nfc_card')
        date_joined_after = self.request.query_params.get('date_joined_after')
        date_joined_before = self.request.query_params.get('date_joined_before')

        # 应用过滤条件
        if is_staff is not None:
            queryset = queryset.filter(is_staff=is_staff.lower() == 'true')

        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')

        if has_face_data is not None:
            if has_face_data.lower() == 'true':
                queryset = queryset.filter(face_data__isnull=False)
            else:
                queryset = queryset.filter(face_data__isnull=True)

        if has_nfc_card is not None:
            if has_nfc_card.lower() == 'true':
                queryset = queryset.filter(profile__nfc_card_id__isnull=False)
            else:
                queryset = queryset.filter(profile__nfc_card_id__isnull=True)

        if date_joined_after:
            queryset = queryset.filter(date_joined__gte=date_joined_after)

        if date_joined_before:
            queryset = queryset.filter(date_joined__lte=date_joined_before)

        return queryset

    def list(self, request, *args, **kwargs):
        """
        重写list方法，添加统计信息
        """
        response = super().list(request, *args, **kwargs)

        # 添加统计信息
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        staff_users = User.objects.filter(is_staff=True).count()
        users_with_face = User.objects.filter(face_data__isnull=False).count()

        response.data['stats'] = {
            'total_users': total_users,
            'active_users': active_users,
            'staff_users': staff_users,
            'users_with_face': users_with_face,
        }

        return response

class AdminUserCreateAPI(generics.CreateAPIView):
    """
    管理员创建用户API
    """
    serializer_class = AdminUserCreateSerializer
    permission_classes = [permissions.IsAdminUser]

    def create(self, request, *args, **kwargs):
        """
        创建用户并返回详细信息
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 返回创建的用户详细信息
        user_serializer = AdminUserSerializer(user)
        return Response(user_serializer.data, status=status.HTTP_201_CREATED)

class AdminUserDetailAPI(generics.RetrieveAPIView):
    """
    管理员获取用户详情API
    """
    queryset = User.objects.select_related('profile').prefetch_related('access_logs', 'face_data')
    serializer_class = AdminUserSerializer
    permission_classes = [permissions.IsAdminUser]

class AdminUserUpdateAPI(generics.UpdateAPIView):
    """
    管理员更新用户API
    """
    queryset = User.objects.all()
    serializer_class = AdminUserUpdateSerializer
    permission_classes = [permissions.IsAdminUser]

    def update(self, request, *args, **kwargs):
        """
        更新用户并返回详细信息
        """
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 返回更新后的用户详细信息
        user_serializer = AdminUserSerializer(user)
        return Response(user_serializer.data)

class AdminUserDeleteAPI(generics.DestroyAPIView):
    """
    管理员删除用户API
    """
    queryset = User.objects.all()
    permission_classes = [permissions.IsAdminUser]

    def destroy(self, request, *args, **kwargs):
        """
        删除用户前进行安全检查
        """
        instance = self.get_object()

        # 防止删除自己
        if instance.id == request.user.id:
            return Response({
                'error': '不能删除自己的账户'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 防止删除超级管理员（如果当前用户不是超级管理员）
        if instance.is_superuser and not request.user.is_superuser:
            return Response({
                'error': '没有权限删除超级管理员账户'
            }, status=status.HTTP_403_FORBIDDEN)

        # 记录删除操作（可选：添加到日志系统）
        username = instance.username

        # 执行删除
        self.perform_destroy(instance)

        return Response({
            'message': f'用户 {username} 已成功删除'
        }, status=status.HTTP_200_OK)

class AdminUserBatchAPI(APIView):
    """
    管理员批量操作用户API
    """
    permission_classes = [permissions.IsAdminUser]

    def post(self, request):
        """
        执行批量操作
        """
        serializer = AdminUserBatchSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        user_ids = serializer.validated_data['user_ids']
        action = serializer.validated_data['action']

        # 获取要操作的用户
        users = User.objects.filter(id__in=user_ids)

        if not users.exists():
            return Response({
                'error': '未找到指定的用户'
            }, status=status.HTTP_404_NOT_FOUND)

        # 安全检查：防止操作自己
        if request.user.id in user_ids:
            return Response({
                'error': '不能对自己执行批量操作'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 执行批量操作
        success_count = 0
        failed_users = []

        for user in users:
            try:
                if action == 'activate':
                    user.is_active = True
                    user.save()
                    success_count += 1

                elif action == 'deactivate':
                    user.is_active = False
                    user.save()
                    success_count += 1

                elif action == 'make_staff':
                    user.is_staff = True
                    user.save()
                    success_count += 1

                elif action == 'remove_staff':
                    # 防止移除超级管理员的staff权限
                    if user.is_superuser and not request.user.is_superuser:
                        failed_users.append(f'{user.username} (超级管理员)')
                        continue
                    user.is_staff = False
                    user.save()
                    success_count += 1

                elif action == 'delete':
                    # 防止删除超级管理员
                    if user.is_superuser and not request.user.is_superuser:
                        failed_users.append(f'{user.username} (超级管理员)')
                        continue
                    user.delete()
                    success_count += 1

            except Exception as e:
                failed_users.append(f'{user.username} (错误: {str(e)})')

        # 返回操作结果
        result = {
            'message': f'批量操作完成',
            'success_count': success_count,
            'total_count': len(user_ids),
            'action': action
        }

        if failed_users:
            result['failed_users'] = failed_users

        return Response(result, status=status.HTTP_200_OK)

class AdminUserStatsAPI(APIView):
    """
    管理员获取用户统计信息API
    """
    permission_classes = [permissions.IsAdminUser]

    def get(self, request):
        """
        获取详细的用户统计信息
        """
        from django.utils import timezone
        from datetime import timedelta

        # 基础统计
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        inactive_users = total_users - active_users
        staff_users = User.objects.filter(is_staff=True).count()
        superuser_count = User.objects.filter(is_superuser=True).count()

        # 人脸数据统计
        users_with_face = User.objects.filter(face_data__isnull=False).count()
        users_without_face = total_users - users_with_face

        # NFC卡统计
        users_with_nfc = User.objects.filter(profile__nfc_card_id__isnull=False).count()
        users_without_nfc = total_users - users_with_nfc

        # 时间统计
        now = timezone.now()
        today = now.date()
        week_ago = now - timedelta(days=7)
        month_ago = now - timedelta(days=30)

        new_users_today = User.objects.filter(date_joined__date=today).count()
        new_users_week = User.objects.filter(date_joined__gte=week_ago).count()
        new_users_month = User.objects.filter(date_joined__gte=month_ago).count()

        # 活跃用户统计（基于最后登录时间）
        active_today = User.objects.filter(last_login__date=today).count()
        active_week = User.objects.filter(last_login__gte=week_ago).count()
        active_month = User.objects.filter(last_login__gte=month_ago).count()

        stats = {
            'user_counts': {
                'total': total_users,
                'active': active_users,
                'inactive': inactive_users,
                'staff': staff_users,
                'superuser': superuser_count,
            },
            'feature_usage': {
                'with_face_data': users_with_face,
                'without_face_data': users_without_face,
                'with_nfc_card': users_with_nfc,
                'without_nfc_card': users_without_nfc,
            },
            'registration_trends': {
                'new_today': new_users_today,
                'new_this_week': new_users_week,
                'new_this_month': new_users_month,
            },
            'activity_trends': {
                'active_today': active_today,
                'active_this_week': active_week,
                'active_this_month': active_month,
            },
            'generated_at': now.isoformat(),
        }

        return Response(stats, status=status.HTTP_200_OK)
